package com.hoperun.product.util.scan;

import android.view.KeyEvent;

public class ScanGun {
	public static final int MAX_KEYS_INTERVAL_DEFAULT = 20;
	private long currentTime = 0L;
	private boolean isKeySHIFT = false;
	private StringBuilder stringBuilder = new StringBuilder();
	private ScanGunCallBack callBack = null;

	private static int maxKeysInterval = 20;

	public static void setMaxKeysInterval(int interval) {
		maxKeysInterval = interval;
	}

	public ScanGun(ScanGunCallBack callBack) {
		this.callBack = callBack;
	}

	public boolean isMaybeScanning(int keyCode, KeyEvent event) {
		if (event.getFlags() != 8) {
			return false;
		}
		if (this.currentTime == 0L) {
			if (this.stringBuilder.length() > 0) {
				this.stringBuilder = this.stringBuilder.delete(0,
						this.stringBuilder.length());
			}
			this.currentTime = System.currentTimeMillis();
		} else {
			if ((System.currentTimeMillis() - this.currentTime > maxKeysInterval)
					&& (this.stringBuilder.length() > 0)) {
				this.stringBuilder = this.stringBuilder.delete(0,
						this.stringBuilder.length());
			}

			this.currentTime = System.currentTimeMillis();
		}

		if (keyCode == 59) {
			this.isKeySHIFT = true;
		}

		if (keyCode == 66) {
			this.isKeySHIFT = false;
			this.currentTime = 0L;
			if (this.callBack != null) {
				this.callBack.onScanFinish(this.stringBuilder.toString());
			}
			return true;
		}
		if ((keyCode >= 7) && (keyCode <= 16)) {
			handleTopNumKeys(keyCode);
		} else if ((keyCode >= 29) && (keyCode <= 54)) {
			checkShift((char) (keyCode + 68), (char) (keyCode + 36));
		} else if ((keyCode >= 144) && (keyCode <= 158)) {
			handleNumPadKeys(keyCode);
		} else {
			switch (keyCode) {
			case 68:
				checkShift('`', '~');
				break;
			case 69:
				checkShift('-', '_');
				break;
			case 70:
				checkShift('=', '+');
				break;
			case 71:
				checkShift('[', '{');
				break;
			case 72:
				checkShift(']', '}');
				break;
			case 73:
				checkShift('\\', '|');
				break;
			case 74:
				checkShift(';', ':');
				break;
			case 75:
				checkShift('\'', '"');
				break;
			case 55:
				checkShift(',', '<');
				break;
			case 56:
				checkShift('.', '>');
				break;
			case 76:
				checkShift('/', '?');
				break;
			case 62:
				this.stringBuilder.append(' ');
				break;
			case 57:
			case 58:
			case 59:
			case 60:
			case 61:
			case 63:
			case 64:
			case 65:
			case 66:
			case 67:
			default:
				return false;
			}

			return true;
		}

		return true;
	}

	private void checkShift(char ascallNoShift, char ascallOnShift) {
		if (this.isKeySHIFT) {
			this.stringBuilder.append(ascallOnShift);
			this.isKeySHIFT = false;
		} else {
			this.stringBuilder.append(ascallNoShift);
		}
	}

	private void handleNumPadKeys(int keyCode) {
		if (keyCode <= 153)
			this.stringBuilder.append((char) (keyCode - 96));
		else if (keyCode == 154)
			this.stringBuilder.append('/');
		else if (keyCode == 155)
			this.stringBuilder.append('*');
		else if (keyCode == 156)
			this.stringBuilder.append('-');
		else if (keyCode == 157)
			this.stringBuilder.append('+');
		else if (keyCode == 158)
			this.stringBuilder.append('.');
	}

	private void handleTopNumKeys(int keyCode) {
		if ((keyCode < 7) || (keyCode > 16)) {
			return;
		}
		switch (keyCode) {
		case 7:
			checkShift('0', ')');
			break;
		case 8:
			checkShift('1', '!');
			break;
		case 9:
			checkShift('2', '@');
			break;
		case 10:
			checkShift('3', '#');
			break;
		case 11:
			checkShift('4', '$');
			break;
		case 12:
			checkShift('5', '%');
			break;
		case 13:
			checkShift('6', '^');
			break;
		case 14:
			checkShift('7', '&');
			break;
		case 15:
			checkShift('8', '*');
			break;
		case 16:
			checkShift('9', '(');
			break;
		}
	}

	public static abstract interface ScanGunCallBack {
		public abstract void onScanFinish(String paramString);
	}
}
